#ifndef _HTTPDIGESTCREDENTIALS_HPP_
#define _HTTPDIGESTCREDENTIALS_HPP_

#include "jhdefs.hpp"
#include "net/HTTPAuthenticationParams.hpp"
#include "event/mutex.hpp"
using JHCPP::event::CMutex;

#include <map>
#include <string>

NET_NAMESPACE_BEGIN

class CHTTPRequest;
class CHTTPResponse;
class CHTTPDigestCredentials
{
public:
	CHTTPDigestCredentials();
	CHTTPDigestCredentials(const std::string& username, const std::string& password);
	~CHTTPDigestCredentials();

	void reset();

	void setUsername(const std::string& username);
	const std::string& getUsername() const;
	void setPassword(const std::string& password);
	const std::string& getPassword() const;

	void authenticate(CHTTPRequest& request, const CHTTPResponse& response);
	void authenticate(CHTTPRequest& request, const CHTTPAuthenticationParams& responseAuthParams);

	void updateAuthInfo(CHTTPRequest& request);
	void updateProxyAuthInfo(CHTTPRequest& request);

	void proxyAuthenticate(CHTTPRequest& request, const CHTTPResponse& response);
	void proxyAuthenticate(CHTTPRequest& request, const CHTTPAuthenticationParams& responseAuthParams);

	bool verifyAuthInfo(const CHTTPRequest& request) const;
	bool verifyAuthParams(const CHTTPRequest& request, const CHTTPAuthenticationParams& params) const;

	static std::string createNonce();
	static const std::string SCHEME;

private:
	CHTTPDigestCredentials(const CHTTPDigestCredentials&);
	CHTTPDigestCredentials& operator = (const CHTTPDigestCredentials&);

	void createAuthParams(const CHTTPRequest& request, const CHTTPAuthenticationParams& responseAuthParams);
	void updateAuthParams(const CHTTPRequest& request);
	int updateNonceCounter(const std::string& nonce);

	static const std::string DEFAULT_ALGORITHM;
	static const std::string DEFAULT_QOP;
	static const std::string NONCE_PARAM;
	static const std::string REALM_PARAM;
	static const std::string QOP_PARAM;
	static const std::string ALGORITHM_PARAM;
	static const std::string USERNAME_PARAM;
	static const std::string OPAQUE_PARAM;
	static const std::string URI_PARAM;
	static const std::string RESPONSE_PARAM;
	static const std::string AUTH_PARAM;
	static const std::string CNONCE_PARAM;
	static const std::string NC_PARAM;

	typedef std::map<std::string, int> NonceCounterMap;

	std::string					m_username;
	std::string					m_password;
	CHTTPAuthenticationParams	m_requestAuthParams;
	NonceCounterMap				m_nc;

	static int					m_nonceCounter;
	static CMutex				m_nonceMutex;
};


NET_NAMESPACE_END

#endif
